package org.finesys.ai.core.completion;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonNaming;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import static java.util.Collections.unmodifiableList;

@JsonDeserialize(builder = Content.Builder.class)
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public final class Content {
    //输出的 token。
    @JsonProperty
    private String token;
    //该 token 的对数概率。-9999.0 代表该 token 的输出概率极小，不在 top 20 最可能输出的 token 中。
    @JsonProperty
    private Integer logprob;
    //一个包含该 token UTF-8 字节表示的整数列表。一般在一个 UTF-8 字符被拆分成多个 token 来表示时有用。如果 token 没有对应的字节表示，则该值为 null。
    @JsonProperty
    private Integer bytes[];
    //一个包含在该输出位置上，输出概率 top N 的 token 的列表，以及它们的对数概率。在罕见情况下，返回的 token 数量可能少于请求参数中指定的 top_logprobs 值。
    @JsonProperty
    private List<TopLogprobs> topLogprobs;


    public Content(Builder builder) {
        this.token = builder.token;
        this.logprob = builder.logprob;
        this.bytes = builder.bytes;
        this.topLogprobs = builder.topLogprobs;
    }

    public String getToken() {
        return token;
    }

    public Integer getLogprob() {
        return logprob;
    }

    public Integer[] getBytes() {
        return bytes;
    }

    public List<TopLogprobs> getTopLogprobs() {
        return topLogprobs;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Content content = (Content) o;
        return Objects.equals(token, content.token) && Objects.equals(logprob, content.logprob) && Objects.deepEquals(bytes, content.bytes) && Objects.equals(topLogprobs, content.topLogprobs);
    }

    @Override
    public int hashCode() {
        return Objects.hash(token, logprob, Arrays.hashCode(bytes), topLogprobs);
    }

    public static class Builder {
        private String token;
        private Integer logprob;
        private Integer bytes[];
        private List<TopLogprobs> topLogprobs;

        private Builder() {

        }

        public Builder setToken(String token) {
            this.token = token;
            return this;
        }

        public Builder setLogprob(Integer logprob) {
            this.logprob = logprob;
            return this;
        }

        public Builder setBytes(Integer bytes[]) {
            this.bytes = bytes;
            return this;
        }

        public Builder setTopLogprobs(List<TopLogprobs> topLogprobs) {
            if (topLogprobs != null) {
                this.topLogprobs = unmodifiableList(topLogprobs);
            }
            return this;
        }

        public Content build() {
            return new Content(this);
        }
    }
}
